#include "ibms_in.h"

#define PREFIX_DSCLOG_ibms_conf			INFOLOGSG( 
#define NEWLINE_DSCLOG_ibms_conf	
#include "IDL_ibms_conf.dsc.LOG.c"

#define JPATH_NODES		"/nodes"
#define JPATH_NODES_NODE	"/nodes/node"
#define JPATH_NODES_INVALID	"/nodes/invalid"
#define JPATH_NODES_HOSTS	"/nodes/hosts"
#define JPATH_NODES_HOSTS_IP	"/nodes/hosts/ip"
#define JPATH_NODES_HOSTS_PORT	"/nodes/hosts/port"

static funcCallbackOnJsonNode CallbackOnJsonNode_nodes_conf ;
int CallbackOnJsonNode_nodes_conf( int type , char *jpath , int jpath_len , int jpath_size , char *node , int node_len , char *content , int content_len , void *p )
{
	struct IbmsEnv			*p_env = (struct IbmsEnv *) p ;
	static struct IbmsNode		*p_node = NULL ;
	static struct IbmsNodeHost	*p_node_host = NULL ;
	
	int				nret = 0 ;
	
	if( type & FASTERJSON_NODE_BRANCH )
	{
		if( type & FASTERJSON_NODE_ENTER )
		{
			if( jpath_len == sizeof(JPATH_NODES)-1 && STRNCMP( jpath , == , JPATH_NODES , sizeof(JPATH_NODES)-1 ) )
			{
				p_node = (struct IbmsNode *)malloc( sizeof(struct IbmsNode) ) ;
				if( p_node == NULL )
				{
					ERRORLOGSG( "malloc failed[%d]" , errno );
					return -1;
				}
				memset( p_node , 0x00 , sizeof(struct IbmsNode) );
			}
			if( jpath_len == sizeof(JPATH_NODES_HOSTS)-1 && STRNCMP( jpath , == , JPATH_NODES_HOSTS , sizeof(JPATH_NODES_HOSTS)-1 ) )
			{
				p_node_host = (struct IbmsNodeHost *)malloc( sizeof(struct IbmsNodeHost) ) ;
				if( p_node == NULL )
				{
					ERRORLOGSG( "malloc failed[%d]" , errno );
					return -1;
				}
				memset( p_node_host , 0x00 , sizeof(struct IbmsNodeHost) );
			}
		}
		else if( type & FASTERJSON_NODE_LEAVE )
		{
			if( jpath_len == sizeof(JPATH_NODES)-1 && STRNCMP( jpath , == , JPATH_NODES , sizeof(JPATH_NODES)-1 ) )
			{
				INFOLOGSG( "load node[%s][%d]" , p_node->node , p_node->invalid );
				
				nret = LinkIbmsNodeTreeNode( p_env , p_node ) ;
				if( nret )
				{
					ERRORLOGSG( "LinkIbmsNodeTreeNode[%s] failed[%d]" , p_node->node , nret );
					return -1;
				}
				p_node = NULL ;
			}
			else if( jpath_len == sizeof(JPATH_NODES_HOSTS)-1 && STRNCMP( jpath , == , JPATH_NODES_HOSTS , sizeof(JPATH_NODES_HOSTS)-1 ) )
			{
#if 0
				p_node_host->invalid = 1 ;
				INFOLOGSG( "load node_host[%s][%d][%d]" , p_node_host->ip , p_node_host->port , p_node_host->invalid );
#endif
				
				nret = LinkIbmsNodeHostTreeNode( p_node , p_node_host ) ;
				if( nret )
				{
					ERRORLOGSG( "LinkIbmsNodeHostTreeNode[%s][%s][%d] failed[%d]" , p_node->node , p_node_host->ip , p_node_host->port , nret );
					return -1;
				}
				p_node_host = NULL ;
			}
		}
	}
	else if( type & FASTERJSON_NODE_LEAF )
	{
		if( jpath_len == sizeof(JPATH_NODES_NODE)-1 && STRNCMP( jpath , == , JPATH_NODES_NODE , sizeof(JPATH_NODES_NODE)-1 ) )
		{
			if( content_len > IBP_MAXLEN_NODE )
			{
				ERRORLOGSG( "node[%.*s] too long" , content_len , content );
				return -1;
			}
			
			strncpy( p_node->node , content , content_len ) ;
		}
		else if( jpath_len == sizeof(JPATH_NODES_INVALID)-1 && STRNCMP( jpath , == , JPATH_NODES_INVALID , sizeof(JPATH_NODES_INVALID)-1 ) )
		{
			p_node->invalid = nstoi( content , content_len ) ;
		}
		else if( jpath_len == sizeof(JPATH_NODES_HOSTS_IP)-1 && STRNCMP( jpath , == , JPATH_NODES_HOSTS_IP , sizeof(JPATH_NODES_HOSTS_IP)-1 ) )
		{
			if( content_len > IBP_MAXLEN_NODE_IP )
			{
				ERRORLOGSG( "node[%s] ip[%.*s] too long" , p_node->node , content_len , content );
				return -1;
			}
			
			strncpy( p_node_host->ip , content , content_len ) ;
		}
		else if( jpath_len == sizeof(JPATH_NODES_HOSTS_PORT)-1 && STRNCMP( jpath , == , JPATH_NODES_HOSTS_PORT , sizeof(JPATH_NODES_HOSTS_PORT)-1 ) )
		{
			p_node_host->port = nstoi( content , content_len ) ;
		}
	}
	
	return 0;
}

#define JPATH_APPS		"/apps"
#define JPATH_APPS_APP		"/apps/app"
#define JPATH_APPS_DESC		"/apps/desc"
#define JPATH_APPS_BIN		"/apps/bin"
#define JPATH_APPS_TIMEOUT	"/apps/timeout"
#define JPATH_APPS_TIMEOUT2	"/apps/timeout2"
#define JPATH_APPS_INVALID	"/apps/invalid"

static funcCallbackOnJsonNode CallbackOnJsonNode_apps_conf ;
int CallbackOnJsonNode_apps_conf( int type , char *jpath , int jpath_len , int jpath_size , char *app , int app_len , char *content , int content_len , void *p )
{
	struct IbmsEnv			*p_env = (struct IbmsEnv *) p ;
	static struct IbmsApp		*p_app = NULL ;
	
	int				nret = 0 ;
	
	if( type & FASTERJSON_NODE_BRANCH )
	{
		if( type & FASTERJSON_NODE_ENTER )
		{
			if( jpath_len == sizeof(JPATH_APPS)-1 && STRNCMP( jpath , == , JPATH_APPS , sizeof(JPATH_APPS)-1 ) )
			{
				p_app = (struct IbmsApp *)malloc( sizeof(struct IbmsApp) ) ;
				if( p_app == NULL )
				{
					ERRORLOGSG( "malloc failed[%d]" , errno );
					return -1;
				}
				memset( p_app , 0x00 , sizeof(struct IbmsApp) );
			}
		}
		else if( type & FASTERJSON_NODE_LEAVE )
		{
			if( jpath_len == sizeof(JPATH_APPS)-1 && STRNCMP( jpath , == , JPATH_APPS , sizeof(JPATH_APPS)-1 ) )
			{
				INFOLOGSG( "load app[%s][%s][%s][%d][%d][%d]" , p_app->app , p_app->desc , p_app->bin , p_app->timeout , p_app->timeout2 , p_app->invalid );
				
				nret = LinkIbmsAppTreeNode( p_env , p_app ) ;
				if( nret )
				{
					ERRORLOGSG( "LinkIbmsAppTreeNode[%s] failed[%d]" , p_app->app , nret );
					return -1;
				}
				p_app = NULL ;
			}
		}
	}
	else if( type & FASTERJSON_NODE_LEAF )
	{
		if( jpath_len == sizeof(JPATH_APPS_APP)-1 && STRNCMP( jpath , == , JPATH_APPS_APP , sizeof(JPATH_APPS_APP)-1 ) )
		{
			if( content_len > IBP_MAXLEN_NODE )
			{
				ERRORLOGSG( "app[%.*s] too long" , content_len , content );
				return -1;
			}
			
			strncpy( p_app->app , content , content_len );
		}
		else if( jpath_len == sizeof(JPATH_APPS_DESC)-1 && STRNCMP( jpath , == , JPATH_APPS_DESC , sizeof(JPATH_APPS_DESC)-1 ) )
		{
			if( content_len > IBP_MAXLEN_APP_DESC )
			{
				ERRORLOGSG( "app[%.*s] too long" , content_len , content );
				return -1;
			}
			
			strncpy( p_app->desc , content , content_len );
		}
		else if( jpath_len == sizeof(JPATH_APPS_BIN)-1 && STRNCMP( jpath , == , JPATH_APPS_BIN , sizeof(JPATH_APPS_BIN)-1 ) )
		{
			if( content_len > IBP_MAXLEN_APP_BIN )
			{
				ERRORLOGSG( "app[%.*s] too long" , content_len , content );
				return -1;
			}
			
			strncpy( p_app->bin , content , content_len );
		}
		else if( jpath_len == sizeof(JPATH_APPS_TIMEOUT)-1 && STRNCMP( jpath , == , JPATH_APPS_TIMEOUT , sizeof(JPATH_APPS_TIMEOUT)-1 ) )
		{
			p_app->timeout = nstoi( content , content_len ) ;
		}
		else if( jpath_len == sizeof(JPATH_APPS_TIMEOUT2)-1 && STRNCMP( jpath , == , JPATH_APPS_TIMEOUT2 , sizeof(JPATH_APPS_TIMEOUT2)-1 ) )
		{
			p_app->timeout2 = nstoi( content , content_len ) ;
		}
		else if( jpath_len == sizeof(JPATH_APPS_INVALID)-1 && STRNCMP( jpath , == , JPATH_APPS_INVALID , sizeof(JPATH_APPS_INVALID)-1 ) )
		{
			p_app->invalid = nstoi( content , content_len ) ;
		}
	}
	
	return 0;
}

#define JPATH_PROJECTS		"/projects"
#define JPATH_PROJECTS_PROJECT	"/projects/project"
#define JPATH_PROJECTS_NODES	"/projects/nodes"
#define JPATH_PROJECTS_APPS	"/projects/apps"

static funcCallbackOnJsonNode CallbackOnJsonNode_projects_conf ;
int CallbackOnJsonNode_projects_conf( int type , char *jpath , int jpath_len , int jpath_size , char *node , int node_len , char *content , int content_len , void *p )
{
	struct IbmsEnv			*p_env = (struct IbmsEnv *) p ;
	static struct IbmsProject	*p_project = NULL ;
	
	int				nret = 0 ;
	
	if( type & FASTERJSON_NODE_BRANCH )
	{
		if( type & FASTERJSON_NODE_ENTER )
		{
			if( jpath_len == sizeof(JPATH_PROJECTS)-1 && STRNCMP( jpath , == , JPATH_PROJECTS , sizeof(JPATH_PROJECTS)-1 ) )
			{
				p_project = (struct IbmsProject *)malloc( sizeof(struct IbmsProject) ) ;
				if( p_project == NULL )
				{
					ERRORLOGSG( "malloc failed[%d]" , errno );
					return -1;
				}
				memset( p_project , 0x00 , sizeof(struct IbmsProject) );
			}
		}
		else if( type & FASTERJSON_NODE_LEAVE )
		{
			if( jpath_len == sizeof(JPATH_PROJECTS)-1 && STRNCMP( jpath , == , JPATH_PROJECTS , sizeof(JPATH_PROJECTS)-1 ) )
			{
				INFOLOGSG( "load project[%s][%s][%s]" , p_project->project , p_project->nodes , p_project->apps );
				
				nret = LinkIbmsProjectTreeNode( p_env , p_project ) ;
				if( nret )
				{
					ERRORLOGSG( "LinkIbmsProjectTreeNode[%s] failed[%d]" , p_project->project , nret );
					return -1;
				}
				p_project = NULL ;
			}
		}
	}
	else if( type & FASTERJSON_NODE_LEAF )
	{
		if( jpath_len == sizeof(JPATH_PROJECTS_PROJECT)-1 && STRNCMP( jpath , == , JPATH_PROJECTS_PROJECT , sizeof(JPATH_PROJECTS_PROJECT)-1 ) )
		{
			if( content_len > IBP_MAXLEN_PROJECT )
			{
				ERRORLOGSG( "project[%.*s] too long" , content_len , content );
				return -1;
			}
			
			strncpy( p_project->project , content , content_len ) ;
		}
		else if( jpath_len == sizeof(JPATH_PROJECTS_NODES)-1 && STRNCMP( jpath , == , JPATH_PROJECTS_NODES , sizeof(JPATH_PROJECTS_NODES)-1 ) )
		{
			p_project->nodes = strndup( content , content_len ) ;
			if( p_project->nodes == NULL )
			{
				ERRORLOGSG( "strndup failed[%d]" , errno );
				return -1;
			}
		}
		else if( jpath_len == sizeof(JPATH_PROJECTS_APPS)-1 && STRNCMP( jpath , == , JPATH_PROJECTS_APPS , sizeof(JPATH_PROJECTS_APPS)-1 ) )
		{
			p_project->apps = strndup( content , content_len ) ;
			if( p_project->apps == NULL )
			{
				ERRORLOGSG( "strndup failed[%d]" , errno );
				return -1;
			}
		}
	}
	
	return 0;
}

int LoadConfig( struct IbmsEnv *p_env )
{
	char		*file_content = NULL ;
	int		file_len ;
	
	char		jpath[ 1024 + 1 ] ;
	
	int		nret = 0 ;
	
	file_content = StrdupEntireFile( p_env->ibms_conf_pathfilename , & file_len ) ;
	if( file_content == NULL )
	{
		ERRORLOGSG( "StrdupEntireFile[%s] failed" , p_env->ibms_conf_pathfilename );
		return -1;
	}
	
	nret = DSCDESERIALIZE_JSON_ibms_conf( "GB18030" , file_content , & file_len , & (p_env->ibms_conf) ) ;
	free( file_content );
	if( nret )
	{
		ERRORLOGSG( "DSCDESERIALIZE_JSON_ibms_conf[%s] failed[%d]" , p_env->ibms_conf_pathfilename , nret );
		return -1;
	}
	
	DSCLOG_ibms_conf( & (p_env->ibms_conf) );
	
	memset( p_env->nodes_conf_pathfilename , 0x00 , sizeof(p_env->nodes_conf_pathfilename) );
	snprintf( p_env->nodes_conf_pathfilename , sizeof(p_env->nodes_conf_pathfilename)-1 , "%s/etc/%s" , getenv("HOME") , p_env->ibms_conf.ibms.config.nodes_conf );
	file_content = StrdupEntireFile( p_env->nodes_conf_pathfilename , & file_len ) ;
	if( file_content == NULL )
	{
		ERRORLOGSG( "StrdupEntireFile[%s] failed" , p_env->nodes_conf_pathfilename );
		return -1;
	}
	
	memset( jpath , 0x00 , sizeof(jpath) );
	nret = TravelJsonBuffer( file_content , jpath , sizeof(jpath)-1 , & CallbackOnJsonNode_nodes_conf , p_env ) ;
	if( nret )
	{
		ERRORLOGSG( "TravelJsonBuffer CallbackOnJsonNode_nodes_conf failed[%d]" , p_env->nodes_conf_pathfilename , nret );
		free( file_content );
		return -1;
	}
	
	free( file_content );
	
	memset( p_env->apps_conf_pathfilename , 0x00 , sizeof(p_env->apps_conf_pathfilename) );
	snprintf( p_env->apps_conf_pathfilename , sizeof(p_env->apps_conf_pathfilename)-1 , "%s/etc/%s" , getenv("HOME") , p_env->ibms_conf.ibms.config.apps_conf );
	file_content = StrdupEntireFile( p_env->apps_conf_pathfilename , & file_len ) ;
	if( file_content == NULL )
	{
		ERRORLOGSG( "StrdupEntireFile[%s] failed" , p_env->apps_conf_pathfilename );
		return -1;
	}
	
	memset( jpath , 0x00 , sizeof(jpath) );
	nret = TravelJsonBuffer( file_content , jpath , sizeof(jpath)-1 , & CallbackOnJsonNode_apps_conf , p_env ) ;
	if( nret )
	{
		ERRORLOGSG( "TravelJsonBuffer CallbackOnJsonNode_apps_conf failed[%d]" , p_env->apps_conf_pathfilename , nret );
		free( file_content );
		return -1;
	}
	
	free( file_content );
	
	memset( p_env->projects_conf_pathfilename , 0x00 , sizeof(p_env->projects_conf_pathfilename) );
	snprintf( p_env->projects_conf_pathfilename , sizeof(p_env->projects_conf_pathfilename)-1 , "%s/etc/%s" , getenv("HOME") , p_env->ibms_conf.ibms.config.projects_conf );
	file_content = StrdupEntireFile( p_env->projects_conf_pathfilename , & file_len ) ;
	if( file_content == NULL )
	{
		ERRORLOGSG( "StrdupEntireFile[%s] failed" , p_env->projects_conf_pathfilename );
		return -1;
	}
	
	memset( jpath , 0x00 , sizeof(jpath) );
	nret = TravelJsonBuffer( file_content , jpath , sizeof(jpath)-1 , & CallbackOnJsonNode_projects_conf , p_env ) ;
	if( nret )
	{
		ERRORLOGSG( "TravelJsonBuffer CallbackOnJsonNode_projects_conf failed[%d]" , p_env->projects_conf_pathfilename , nret );
		free( file_content );
		return -1;
	}
	
	free( file_content );
	
	return 0;
}

